#include "ObliqueNodeInfo.h"
#include "ObliqueUtil.h"

namespace OCPP
{
	using namespace Cesium;
	
	void ObliqueNodeInfo::fromJson(Json::Value& value)
	{
		auto& info = value["NodeInfo"];
		numGeode = info["numGeode"].asUInt();
		numVertex = info["numVertex"].asUInt();
		numBytesOfImage = info["numBytesOfImage"].asUInt();
		fileName = info["fileName"].asString();
		nodeDepth = info["nodeDepth"].asUInt();
		tileLevel = info["tileLevel"].asUInt();
		tileID = info["tileID"].asString();
		String boundingBoxStr = info["boundingBox"].asString();
		boundingBox = str2box(boundingBoxStr);

		Json::Value imageSizesObj = info["imageSizes"];
		if (!imageSizesObj.isNull())
		{
			for (auto& obj : imageSizesObj)
			{
				StringVector sv = StringUtil::split(obj.asString(),",");
				Vector2i size = { std::stoi(sv[0]) ,std::stoi(sv[1]) };
				imageSizes.push_back(size);
			}
		}

		auto& childrenObj = value["children"];
		if (!childrenObj.isNull())
		{
			for (auto& obj : childrenObj)
			{
				ObliqueNodeInfo nodeInfo;
				nodeInfo.fromJson(obj);
				children.push_back(nodeInfo);
			}
		}
	}
	
	void ObliqueNodeInfo::statistic(ObliqueTileStatistic* statstic1)
	{
		if (statstic1)
		{
			long numPixels = 0;
			for (auto& s : imageSizes)
			{
				int w = s[0];
				int h = s[1];
				numPixels += (w * h);
			}

			statstic1->countNumGeodePerLevel(numGeode, nodeDepth, boundingBox, numPixels);
		}

		for (auto& child : children)
		{
			child.statistic(statstic1);
		}
	}
		
	Json::Value ObliqueNodeInfo::toJson()
	{
		Json::Value value;
		
		Json::Value info;
		info["numGeode"] = numGeode;
		info["numVertex"] = numVertex;
		info["numBytesOfImage"] = numBytesOfImage;
		info["tileID"] = tileID;
		info["fileName"] = fileName;
		info["nodeDepth"] = nodeDepth;
		info["tileLevel"] = tileLevel;
		info["boundingBox"] = box2string(boundingBox);
		info["boundingSize"] = box2size(boundingBox);
		
		long numPixels = 0;
		Json::Value imageSizesValue;
		for (auto& s : imageSizes)
		{
			int w = s[0];
			int h = s[1];
			numPixels += (w * h);
			imageSizesValue.append(str_format("%d,%d", w, h));
		}
		info["imageSizes"] = imageSizesValue;

		value["NodeInfo"] = info;

		Json::Value childrenValue;
		for (auto& child : children)
		{
			childrenValue.append(child.toJson());
		}

		value["children"] = childrenValue;

		return value;
	}

	void ObliqueNodeInfo::insertChild(ObliqueNodeInfo child)
	{
		boundingBox.expandBy(child.boundingBox);
		children.push_back(child);
	}

	void ObliqueNodeInfo::count(osg::BoundingBox& bound)
	{
		if (bound.xMax() - bound.xMin() > 0.0f)
		{
			boundingBox.expandBy(bound);
		}
		numGeode++;
	}
}